package com.bonc.web.filter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
  * @Description: 登录过滤器
  * @Author: ChenZhiXiang
  * @CreateDate: 2018/12/19 0019 15:28
  * @Version: 1.0
* */
public class LoginFilter implements Filter {

    private String csrfUrl;
    private String loginHtml;
    private String hostValue;
    private Boolean corsFlag;

    private Logger logger = LoggerFactory.getLogger(LoginFilter.class);

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        csrfUrl = arg0.getInitParameter("csrfUrl");
        loginHtml = arg0.getInitParameter("loginHtml");
        corsFlag = Boolean.valueOf(arg0.getInitParameter("corsFlag"));
        hostValue = arg0.getInitParameter("hostValue");

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {

        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;
        String origin = req.getHeader("Origin");
        // 缓存不清除将导致浏览器保存之前页面，可以直接进入
        resp.setHeader("Expires", "-1");
        resp.setHeader("Cache-Control", "no-cache, no-store, must-revalidate");
        resp.setHeader("pragma", "no-cache");
        // 获得当前请求的URI
        String nowPath = req.getRequestURI();
        // 从 HTTP 头中取得 Referer 值
        String referer = req.getHeader("Referer");
        String host = req.getHeader("Host");
        // 不过滤静态资源
        if (nowPath.endsWith(".css") || nowPath.endsWith(".js")
                || nowPath.endsWith(".eot") || nowPath.endsWith(".svg")
                || nowPath.endsWith(".ttf") || nowPath.endsWith(".woff")
                || nowPath.endsWith(".png") || nowPath.endsWith(".jpg")
                || nowPath.contains("swagger") || nowPath.contains("wabjars") || nowPath.contains("v2")) {
            //传给下个filter处理
            logger.info("静态资源，放行");
            chain.doFilter(request, resp);
            return;
        } else {
            //登录请求，放行
            if (nowPath.contains("login")) {
                logger.info("登录请求，放行");
                chain.doFilter(request, response);
                return;
            } else {
                // 在session中拿到user信息
                HttpSession session = req.getSession();
                //在这里注意一个问题，用户登录成功后将用户信息存在session中，同时也存了需要权限的URL和用户有权限的URL
               /* LoginUser user = (LoginUser) session.getAttribute("user");*/
                //判断user信息是否存在
                if (true/*null != user && !user.equals("")*/) {
                    //perMap存放着需要验证的Url和用户有权的Url，是一个Map
                    Map<String, Object> map = (Map<String, Object>) session.getAttribute("perMap");
                    //获取到需要验证的url
                    List<String> needPerUrl = (List<String>) map.get("pers");
                    //判断当前请求url是否需要权限验证
                    boolean isAuth = false;
                    //循环遍历
                    for (int i = 0; i < needPerUrl.size(); i++) {
                        if (needPerUrl.get(i).equals(nowPath)) {
                            //需要认证
                            isAuth = true;
                            break;
                        }
                    }
                    if (isAuth) {
                        logger.info(nowPath + "需要验证");
                        //得到用户有权的url
                        List<String> userPerUrl = (List<String>) map.get("userPer");
                        //用户是否有权
                        boolean isPer = false;
                        for (int i = 0; i < userPerUrl.size(); i++) {
                            if (userPerUrl.get(i).equals(nowPath)) {
                                isPer = true;
                                break;
                            }
                        }
                        if (isPer) {
                            logger.info(nowPath + "用户有权");
                            chain.doFilter(request, resp);
                            return;
                        } else {
                            logger.info("用户没有权限");
                            //销毁session
                            session.removeAttribute("perMap");
                            session.removeAttribute("userInfo");
                            session.invalidate();
                            //重定向到无权限页面
                            resp.sendRedirect(hostValue + loginHtml);
                            return;
                        }
                    } else {
                        logger.info(nowPath + "不需要验证");
                        chain.doFilter(request, resp);
                    }
                } else {
                    //user为空，证明没有登录
                    logger.info("user为空，证明没有登录,跳转登录页面");
                    resp.sendRedirect(hostValue + loginHtml);
                }

            }

            //csrf过滤
            if ((!nowPath.contains(".") && referer == null) || !(check(referer) && check(origin) && check(host))) {
                resp.sendRedirect(hostValue + loginHtml);
                System.out.println("csrf跳转");
                return;
            }

        }

    }

    @Override
    public void destroy() { }

    private boolean check(String needToCheck) {

        if (needToCheck == null) {
            return true;
        }

        String[] ipArr = csrfUrl.split(",");

        for (String anIpArr : ipArr) {
            if (needToCheck.trim().startsWith(anIpArr.trim())) {
                return true;
            }
        }
        return false;
    }
}
